#include "FacialRecognition.h"

IplImage * FacialRecognition::inputImage = 0; //Image structure that will store image captured from cam
CvRect FacialRecognition::faceRect;

FacialRecognition::FacialRecognition(void)
{	
}

void FacialRecognition::Run(int argc, char * argv[])
{
	CaptureFromCAMAndDetectFace(argc, argv);
}

void FacialRecognition::CaptureFromCAMAndDetectFace(int argc, char * argv[])
{
	LearningAndRecognition learning;
	std::stringstream ss;
	std::string cascadeString;
	ss << argv[1];
	ss >> cascadeString;
	cascadeString += "\\haarcascade_frontalface_alt2.xml";
	const char * CASCADE = cascadeString.c_str();
	
	//Load the cascade
	CvHaarClassifierCascade * faceCascade = LoadCascade(CASCADE);

	//Capture structure
	//capture = 0;

	//Capture from the first cam on laptop
	//capture = cvCaptureFromCAM(0);

	/*if(!capture){
		std::cout << "Could not initialize capturing...\n";
		system("pause");
		exit(1);
	}*/

	//else {
		//Start learning and recognition thread
		//learning = new LearningAndRecognition;
		//thread.Run(learning,&LearningAndRecognition::LearnAndRecognizeFace, 1);	//Start thread for face learning
		//delete learning;
		CaptureImageFromCAMAndDetectThenRecognizeFaceInImage(argc, argv, faceCascade);
		learning.LearnAndRecognizeFace(argv);

		// Release cascade
		cvReleaseHaarClassifierCascade(&faceCascade);

		//Release camera
		//cvReleaseCapture(&capture);
	//}	
}

CvHaarClassifierCascade * FacialRecognition::LoadCascade(const char * faceCascadeFilename)
{
	//Load the cascade
	CvHaarClassifierCascade * faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename, 0, 0, 0);

	if(!faceCascade) {
		std::cout << "Could not load face detector " << faceCascadeFilename;
		system("pause");
		exit(1);
	}

	return faceCascade;
}

void FacialRecognition::CaptureImageFromCAMAndDetectThenRecognizeFaceInImage(int argc, char * argv[], CvHaarClassifierCascade * faceCascade)
{
	char * INPUT_IMAGE;

	if(argc == 3) {
		INPUT_IMAGE = argv[2];
	}
	else {
		exit(1);
	}

	//Load input image
	inputImage = cvLoadImage(INPUT_IMAGE, 1);

	//Return detected face as rect
	faceRect = detection.DetectFaceInImage(inputImage, faceCascade);

	//Make sure a valid face was detected
	if (faceRect.width > 0) {

		//std::cout << "Detected a face at " << faceRect.x << "," << faceRect.y << " ";

		//Set the points for detection rect
		pt1.x = faceRect.x;
		pt1.y = faceRect.y;
		pt2.x = faceRect.x + faceRect.width;
		pt2.y = faceRect.y + faceRect.height;

		if(faceRect.width >= CapturingAndStoring::FACE_WIDTH && faceRect.width <= CapturingAndStoring::FACE_WIDTH + 40 
			&& faceRect.height >= CapturingAndStoring::FACE_HEIGHT && faceRect.height <= CapturingAndStoring::FACE_HEIGHT + 40)
			//Put rect on image (GREEN)
			cvRectangle(inputImage,pt1,pt2, CV_RGB(0,255,0), 3, 8, 0 );
		else
			//Put rect on image (RED)
			cvRectangle(inputImage,pt1,pt2, CV_RGB(255,0,0), 3, 8, 0 );			
	}

	//while(true) {		

		//Get the latest frame
		//inputImage = cvQueryFrame(capture);

		//if(!inputImage || faceRect.width < 0)
			//break;

		//Display detection image
		cvShowImage("detection", inputImage);				

		//A delay to restrict the number of images taken pr. second
		int c = cvWaitKey(20);

		//if((char)c == 27 )
			//break;
	//}
}

FacialRecognition::~FacialRecognition(void)
{
}